﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Forms;
using sharpCmd.Classes;

namespace sharpCmd.Controls.FileSystemViewers
{
    public class FileSystemViewer : UserControl, IFileSystemViewer
    {
        public FileSystemViewer()
        {
        }

        /// <summary>
        /// The control that displays filesystem - listview, tree
        /// </summary>
        protected Control ViewControl;

        protected IEnumerable<FSObjectInfo> GetFSInfos()
        {
            DirectoryInfo di = new DirectoryInfo(Path);
            var dirs = di.GetDirectories().OrderBy(p => p.Name).Select(p => new FSObjectInfo()
            {
                FullName = p.FullName,
                Name = p.Name,
                Size = FSObjectInfo.DIRECTORY_INITIAL_SIZE,
                LastWriteTime = p.LastWriteTime,
                Type = FSObjectType.Directory,
                Attributes = p.Attributes
            });
            var files = di.GetFiles().OrderBy(p => p.Name).Select(p => new FSObjectInfo()
            {
                FullName = p.FullName,
                Name = System.IO.Path.GetFileNameWithoutExtension(p.FullName),
                Extension = p.GetExtension(),
                Size = p.Length,
                LastWriteTime = p.LastWriteTime,
                Type = FSObjectType.File,
                Attributes = p.Attributes
            });
            if (di.Parent != null)
                return (new FSObjectInfo[] 
                { new FSObjectInfo() 
                {   FullName = di.Parent.FullName, 
                    Size = FSObjectInfo.DIRECTORY_INITIAL_SIZE,
                    LastWriteTime = di.Parent.LastWriteTime, 
                    Type = FSObjectType.Directory,
                    Name = "..",
                    Fake = true,
                    AlwaysOnTop = true
                } 
                }).Concat(dirs).Concat(files);
            return dirs.Concat(files);
        }


        protected string path;
        public virtual string Path { get; set; }

        public string GetHeader()
        {
            DirectoryInfo di = new DirectoryInfo(Path);
            return di.Name;
        }

        public virtual event Util.DriveChangedDelegate DriveChanged;
        public virtual event Util.PathChangedDelegate PathChanged;
        public delegate void SelectedIndexChangedHandler(int totalFileCount, int totalDirectoryCount, int selectedFileCount, int selectedDirectoryCount, long totalSize, long selectedSize);
        public virtual event SelectedIndexChangedHandler SelectedIndexChanged;


        /// <summary>
        /// Gets first selected item OR a focused item
        /// </summary>
        public virtual FSObjectInfo SelectedItem { get { throw new NotImplementedException(); } }

        /// <summary>
        /// Returns if this viewer has a selected item
        /// </summary>
        public virtual bool HasSelectedItem { get { throw new NotImplementedException(); } }

        public virtual FSObjectInfo FocusedItem { get { throw new NotImplementedException(); } }

        public virtual IEnumerable<FSObjectInfo> SelectedItemInfos { get { throw new NotImplementedException(); } }

        public virtual void Reload()
        {
            throw new NotImplementedException();
        }

        public virtual void OnDriveChanged(string drive)
        {
            throw new NotImplementedException();
        }

        public virtual void DoFocus()
        {
            ViewControl.Focus();
        }

        /// <summary>
        /// Go one directory up
        /// </summary>
        internal void GoToParentDirectory()
        {
            DirectoryInfo di = new DirectoryInfo(Path);
            if (di.Parent == null)
                return;
            Path = di.Parent.FullName;
        }

        /// <summary>
        /// Go to the root directory
        /// </summary>
        internal void GoToRootDirectory()
        {
            DirectoryInfo di = new DirectoryInfo(Path);
            Path = di.Root.FullName;
        }

        internal virtual void Sort(SortType sortType)
        {
            throw new NotImplementedException();
        }

        internal enum SortType
        {
            Name,
            Extension,
            Size,
            Date
        }
    }
}